package com.sumainfor.pc.gmio.service.impl;

import com.sumainfor.common.Constants;
import com.sumainfor.common.util.ContextUtils;
import com.sumainfor.common.util.DateUtils;
import com.sumainfor.common.util.JsonResult;
import com.sumainfor.common.utlis.ComUtils;
import com.sumainfor.common.utlis.ParamsCommon;
import com.sumainfor.pc.gmio.dao.DiDeferredApplyMapper;
import com.sumainfor.pc.gmio.dao.DiForceMapper;
import com.sumainfor.pc.gmio.dao.UtilsMapper;
import com.sumainfor.pc.gmio.feign.Zfeign.ZpcMktFeign;
import com.sumainfor.pc.gmio.feign.Zfeign.ZzuulFeign;
import com.sumainfor.pc.gmio.feign.extend.HouseFeign;
import com.sumainfor.pc.gmio.service.DiDeferredApplyService;
import com.sumainfor.pc.gmio.service.DiForceService;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 延期
 */
@Service
public class DiDeferredApplySerivceImpl implements DiDeferredApplyService {

    private ReentrantLock lock = new ReentrantLock(false);
    Logger log = LoggerFactory.getLogger(DiDeferredApplySerivceImpl.class);
    @Autowired
    private DiDeferredApplyMapper diDeferredApplyMapper;
    @Autowired
    private UtilsMapper utilsMapper;
    @Autowired
    private ZpcMktFeign zpcMktFeign;

    @Autowired
    HouseFeign HouseFeign;
    /**
     * 延期退申请
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult addDi(Map<String, Object> params) {
        JsonResult result = new JsonResult();
        /**
         * 加锁操作
         */
        lock.lock();
        try {
            try {
                if(params.get("PaId")==null || params.get("HouId")==null || params.get("HouInfoId")==null
                        || params.get("TenId")==null || params.get("StartTime")==null || params.get("EndTime")==null
                            || params.get("DailyRent")==null || params.get("TotalAmount")==null){
                    return  result.putFailed("参数不正确");
                }
                //内码
                String UUID="";
                int number=0;
                Map<String,Object>uuid=utilsMapper.getUUID(new HashMap<String,Object>(){{
                    put("uuid", "DefId");
                    put("database", Constants.DATA_SOURCE_GMIO);
                    put("surface", "tcgmio_deferred_apply");
                }});

                if(uuid!=null &&(!uuid.get("uuid").toString().equals(""))){
                    number=Integer.valueOf(uuid.get("uuid").toString());
                    UUID= ComUtils.getLocalTrmSeqNum("da",number);
                }else{
                    UUID=ComUtils.getLocalTrmSeqNum("da",0);
                }
                params.put("DefId",UUID);//内码
                params.put("by", "auto");//操作人
                params.put("term", "1");// 更新端 Update端： 1 租客端 2市场部 3 工程部   4运营部   5财务部  6总经办 7发展部
                params.put("fnc",
                        this.getClass().getSimpleName() + "." + Thread.currentThread().getStackTrace()[1].getMethodName());// 创建Function名
                ParamsCommon.commonInsertParms(params);
                params.put("ApplyTime", params.get("instm"));//违约退申请时间
                //zc修改重新计算存到延期退申请表里面的数据

                //合同月租金
                BigDecimal pactMoney=new BigDecimal(params.get("PactMoney").toString());
                //延期日租金
                BigDecimal dayMoney=new BigDecimal("0");
                //延期总金额
                BigDecimal daySumMoney=new BigDecimal("0");
                //延期开始时间
                String beginDate=params.get("StartTime").toString();
                //延期结束时间
                String endDate=params.get("EndTime").toString();
                //判断两个时间是否在一个月内 true 同一个月  false 不在同一个月
                Boolean ifDateOfMonth= DateUtils.checkMonth(beginDate,endDate);
                System.out.println("是否在同一个月:"+ifDateOfMonth);
                if (ifDateOfMonth){//在同一个月
                    //两个日期之间相差的天数
                    Integer dayCount=DateUtils.betweenDay(beginDate,endDate);
                    //获取时间所在的月份有多少天
                    Integer count=DateUtils.getMonthOfDay(beginDate);
                    //合同月租金/延期开始时间所在的月份天数(除法 四舍五入 保留两位小数)
                    dayMoney=pactMoney.divide(new BigDecimal(String.valueOf(count)),2,BigDecimal.ROUND_HALF_UP);
                    //延期总金额=延期日租金*延期天数*2（延期金额=日租金乘以2 ）
                    daySumMoney=dayMoney.multiply(new BigDecimal("2")).multiply(new BigDecimal(String.valueOf(dayCount)));
                }else{//不在同一个月
                    //获取延期开始时间月份的天数
                    Integer beginCount=DateUtils.getMonthOfDay(beginDate);
                    //获取延期结束时间月份的天数
                    Integer endCount=DateUtils.getMonthOfDay(endDate);
                    //计算延期开始时间和延期开始时间所在月的最后一天相差天数
                    Integer beginDayCount=DateUtils.betweenDay(beginDate,DateUtils.getMonthLastDay(beginDate));
                    //计算延期结束时间和延期结束时间所在月的第一天相差天数
                    Integer endDayCount=DateUtils.betweenDay(DateUtils.getMonthFirstDay(endDate),endDate);
                    //（ (2000/31) X4+(2000/30)x3）/7 上半金额
                    BigDecimal beginMoney=pactMoney.divide(new BigDecimal(String.valueOf(beginCount)),2,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(String.valueOf(beginDayCount)));
                    //下半金额
                    BigDecimal endMoney=pactMoney.divide(new BigDecimal(String.valueOf(endCount)),2,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(String.valueOf(endDayCount)));
                    //延期总金额 （延期金额=日租金乘以2 ）
                    daySumMoney=beginMoney.add(endMoney).multiply(new BigDecimal("2"));
                    //延期日租金
                    dayMoney=(beginMoney.add(endMoney)).divide(new BigDecimal(String.valueOf(beginDayCount+endDayCount)),2,BigDecimal.ROUND_HALF_UP);
                }

                params.put("DailyRent",dayMoney);//日租金
                params.put("TotalAmount",daySumMoney);//合计金额





                Integer count=diDeferredApplyMapper.addDi(params);
                if (count > 0) {
                    result.putSuccess("操作成功");
                } else {
                    result.putFailed("服务器繁忙");
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                }
            } catch (Exception e) {
                result.putFailed("服务器繁忙");
                e.printStackTrace();
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            }
        } finally {
            lock.unlock();
        }
        return result;
    }
    /**
     * 查询延期申请列表
     */
    @Override
    public List<Map<String,Object>> getDiDeferredApplyList(Map<String,Object> params){
        List<Map<String,Object>> list=diDeferredApplyMapper.getDiDeferredApplyList(params);
        List<String> houInfoIdList=new ArrayList<String>();
        for (Map<String,Object> map : list){
            if (map.get("HouInfoId")!=null){
                houInfoIdList.add(map.get("HouInfoId").toString());
            }
        }
        //到市场部查询房源信息
        params.put("houInfoIdList",houInfoIdList);
        JsonResult result=zpcMktFeign.getHouPactApplyList(params);
        System.out.println("市场部返回的参数:"+result);
        if (result.get("errorCode").equals("0")) {
            //市场部的房源列表
            List<Map<String,Object>> mktlist=(List<Map<String,Object>>)result.get("result");
            for (Map<String,Object> giomap : list){
                if (giomap.get("HouInfoId")!=null){
                    for (Map<String,Object> mktmap : mktlist) {
                        if (mktmap.get("HouInfoId")!=null) {
                            if (MapUtils.getString(giomap, "HouInfoId").equals(MapUtils.getString(mktmap, "HouInfoId"))) {
                                giomap.putAll(mktmap);
                            }
                        }
                    }
                }

            }
        }
        return list;
    }
    /*
     * 查询延期申请列表总数
     * */
    public Integer getDiDeferredApplyListCount(Map<String, Object> params){
        return diDeferredApplyMapper.getDiDeferredApplyListCount(params);
    }
    /**
     * 租客端变更租约查询是否发起过延期退
     */
    @Override
    public Integer getDiDaCount(Map<String, Object> params) {
        return diDeferredApplyMapper.getDiDaCount(params);
    }

    /**
     * 功能描述:
     * 根据延期退编号获取延期退资料,并且根据合同编号获取合同资料
     * @Author zhlu
     * @Description //TODO
     * @Date 2019/7/11 20:28
     */
    @Override
    public Map<String, Object> getDeferredByDefIdMap(Map<String,Object>params) {
        Map<String,Object>DeferredByDefIdMap=diDeferredApplyMapper.getDeferredByDefIdMap(params);
        String TenId=params.get("TenId").toString();
        String PaId=DeferredByDefIdMap.get("PaId").toString();
        params.put("TenId",TenId);
        params.put("PaId",PaId);
        Map<String,Object> getPcatInfoByPaIdAndTenIdMap=HouseFeign.getPcatInfoByPaIdAndTenIdMap(params);
        if(!MapUtils.isEmpty(getPcatInfoByPaIdAndTenIdMap)){
            DeferredByDefIdMap.putAll(getPcatInfoByPaIdAndTenIdMap);
        }
        return DeferredByDefIdMap;
    }
}
